package queue.linked_list;


import queue.QueueInterface;
import java.util.NoSuchElementException;

public class ListQueue<T> implements QueueInterface<T> {
    private ListElement head, tail;

    /*
      After first ListElement was added
      all of next ListElements should contain the same class values.
      Else the method throws the IllegalArgumentException.
    */
    @Override
    public boolean offer(T value) {
        if (head != null &&
                value.getClass() != head.getValue().getClass()) throw new IllegalArgumentException();

        ListElement tmp = new ListElement<>(value);
        if (head == null) {
            head = tail = tmp;
        } else {
            tail.setBefore(tmp);
            tmp.setNext(tail);
            tail = tmp;
        }
        return true;
    }

    @Override
    public T element() {
        T value = peek();
        if (value == null) throw new NoSuchElementException();
        else return value;
    }

    @Override
    public T peek() {
        if (head == null || head.getValue() == null) return null;
        return (T)head.getValue();
    }

    @Override
    public T poll() {
        if (head == null || head.getValue() == null) return null;

        ListElement tmp = head;
        head = head.getBefore();
        if (head != null) head.setNext(null);

        return (T)tmp.getValue();
    }

    @Override
    public T remove() {
        T value = poll();
        if (value == null) throw new NoSuchElementException();
        else return value;
    }

    @Override
    public String toString() {
        if (head == null) return null;
        String str = "";
        ListElement tmp = head;
        while(tmp != null){
            str = str + tmp.getValue();
            if (tmp.getBefore() != null) str = str + " <- ";
            tmp = tmp.getBefore();
        }
        return str;
    }
}
